#include "LineChart.h"
#include "textfunctions.h"
using namespace std;

/**
 *  Write the necessary junk for the top of the chart
 */
static void writeTopBoilerPlateOfLineChart(ostream& out) {
    out << ("<html>\n");
    out << ("<head>\n");
    out << ("<script type=\"text/javascript\" src=\"https://www.google.com/jsapi\"></script>\n");
    out << ("<script type=\"text/javascript\">\n");
    out << ("google.load('visualization', '1.0', {'packages':['corechart']});\n");
    out << ("google.setOnLoadCallback(drawChart);\n");
    out << ("function drawChart() {\n");

}

/**
 *  Write the necessary junk for the top of the chart
 */
static void writeBottomBoilerPlateOfLineChart(ostream& out, const string& title) {
    out << "var options = {title: '" << escapeJavascriptString(title) << "', 'width':800, 'height':800};\n";
    out << "var chart = new google.visualization.LineChart(document.getElementById('chart_div'));\n";
    out << "chart.draw(data, options);\n";
    out << "}\n";
    out << "</script>\n";
    out << "</head>\n";
    out << "<body>\n";
    out << "<div id='chart_div'>\n";
    out << "</body>\n";
    out << "</html>";
}

/**
 *   Write the data of the line chart
 */
static void writeLineChartData(ostream& out,
    const vector<double>& xPoints,
    const vector<double>& yPoints) {
    ASSERT(xPoints.size() == yPoints.size());
    out << "var data = google.visualization.arrayToDataTable([\n";
    out << "['x values','y values'],\n";
    int n = xPoints.size();
    for (int i = 0; i < n; i++) {
        double x = xPoints[i];
        double y = yPoints[i];
        out << "[" << x << ", " << y << "]";
        if (i != n - 1) {
            out << ",";
        }
        out << "\n";
    }
    out << "]);\n";
}

LineChart::LineChart() :
    title("A LineChart") {
}

void LineChart::setTitle(const string& t) {
    title = t;
}

void LineChart::setSeries(const vector<double>& xVec, const vector<double>& yVec) {
    x = xVec;
    y = yVec;
}

void LineChart::writeAsHTML(ostream& out) const {
    writeTopBoilerPlateOfLineChart(out);
    writeLineChartData(out, x, y);
    writeBottomBoilerPlateOfLineChart(out, title);
}

void LineChart::writeAsHTML(const string& file) const {
    ofstream out;
    out.open(file.c_str());
    writeAsHTML(out);
    out.close();
}



//////////////////////////////
//
//   TESTS
//
//////////////////////////////


static void testWriteLineChartData() {
    vector<double> x;
    vector<double> y;
    for (int i = 0; i < 3; i++) {
        x.push_back(i);
        y.push_back(i * i);
    }
    stringstream s;
    writeLineChartData(s, x, y);
    string actual = s.str();
    string expected = string("")
        + "var data = google.visualization.arrayToDataTable([\n"
        + "['x values','y values'],\n"
        + "[0, 0],\n"
        + "[1, 1],\n"
        + "[2, 4]\n"
        + "]);\n";
    cout << actual;
    cout << expected;
    ASSERT(actual == expected);
}

void testLineChart() {
    TEST(testWriteLineChartData);
}